﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using Common.Utilities;
using Common.Utilities.Dispatcher;

namespace Workflows.Components.TextMining.Clustering
{
    /// <summary>
    /// 
    /// </summary>
    [Serializable]
    public class FeatureSetInstruction:InstructionBase
    {
        #region props
        private string _DocumentTermListFilePath;
        /// <summary></summary>
        public string DocumentTermListFilePath
        {
            get
            {
                return this._DocumentTermListFilePath;
            }
            set
            {
                this._DocumentTermListFilePath = value;
            }
        }

        private string _StartingClusterResultFilePath;
        /// <summary></summary>
        public string StartingClusterResultFilePath
        {
            get
            {
                return this._StartingClusterResultFilePath;
            }
            set
            {
                this._StartingClusterResultFilePath = value;
            }
        }

        private string _ClusterResultFileNamePattern;
        /// <summary>
        /// i.e. Hierarchical_Cluster_Result_{0}.xml =>
        /// with iteration # 23, it's 
        /// Hierarchical_Cluster_Result_23.xml
        /// 
        /// if {0} is not present, the cluster result will be 
        /// overwritten during each iteration
        /// </summary>
        public string ClusterResultFileNamePattern
        {
            get
            {
                return this._ClusterResultFileNamePattern;
            }
            set
            {
                this._ClusterResultFileNamePattern = value;
            }
        }

        private string _TermWeightFilePath;
        /// <summary>
        /// this is xml file with the following schema
        /// <Terms>
        ///     <Term TermID="0" Phrase="cardiac" IsFrozen="True" CurrentWeight="2">
        ///         <Iteration Number="1" Weight="1" ClassifierScore="0.9"/>
        ///         <Iteration Number="2" Weight="2" ClassifierScore="1.8"/>
        ///         <Iteration Number="3" Weight="2" ClassifierScore="3.5"/>
        ///     </Term>
        ///     <Term TermID="1" Phrase="cancer disease" IsFrozen="False" CurrentWeight="1.6">
        ///         <Iteration Number="1" Weight="1" ClassifierScore="3"/>
        ///         <Iteration Number="2" Weight="2" ClassifierScore="1.8"/>
        ///         <Iteration Number="3" Weight="1.6" ClassifierScore="3.5"/>
        ///     </Term>
        /// </Terms>
        /// </summary>
        public string TermWeightFilePath
        {
            get
            {
                return this._TermWeightFilePath;
            }
            set
            {
                this._TermWeightFilePath = value;
            }
        }

        private string _IterationFilePath;
        /// <summary>
        /// this is summary of all iterations
        /// <Iterations StartingPerformanceScore="99.23" EndingPerformanceScore="450" StartingClusterResultFilePath="">
        ///     <Iteration Number="1" OverallPerformanceScore="129.75" ClusterResultFilePath=""/>
        /// </Iterations>
        /// </summary>
        public string IterationFilePath
        {
            get
            {
                return this._IterationFilePath;
            }
            set
            {
                this._IterationFilePath = value;
            }
        }
        #endregion

        #region ctor
        /// <summary>
        /// 
        /// </summary>
        public FeatureSetInstruction():base(Guid.Empty,Guid.Empty)
        {
            this._DocumentTermListFilePath = string.Empty;
            this._StartingClusterResultFilePath = string.Empty;
            this._IterationFilePath = string.Empty;
            this._TermWeightFilePath = string.Empty;
            this._ClusterResultFileNamePattern = string.Empty;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="componentID"></param>
        /// <param name="jobTicketID"></param>
        /// <param name="startingClusteringFilePath"></param>
        /// <param name="docTermListFilePath"></param>
        /// <param name="termWeightTrackingFilePath"></param>
        /// <param name="iterationSummaryFilePath"></param>
        /// <param name="clusterResultFileNamePattern"></param>
        public FeatureSetInstruction(Guid componentID, Guid jobTicketID,
            string startingClusteringFilePath,
            string docTermListFilePath,
            string termWeightTrackingFilePath,
            string iterationSummaryFilePath,
            string clusterResultFileNamePattern
                ) 
            : base(componentID, jobTicketID)
        {
            this._StartingClusterResultFilePath = startingClusteringFilePath;
            this._DocumentTermListFilePath = docTermListFilePath;
            this._TermWeightFilePath = termWeightTrackingFilePath;
            this._IterationFilePath = iterationSummaryFilePath;
            this._ClusterResultFileNamePattern = clusterResultFileNamePattern;
        }
        #endregion

        public override InstructionBase Instantiate(XmlNode xNode)
        {
            if (xNode.Attributes.GetNamedItem("Type").Value == this.GetType().FullName)
            {
                FeatureSetInstruction instruction = new FeatureSetInstruction();
                instruction.OwnerComponentID = new Guid(xNode.Attributes.GetNamedItem("ComponentID").Value);
                instruction.OwnerWorkerInstanceID = new Guid(xNode.Attributes.GetNamedItem("WorkerID").Value);
                instruction.SubmitTime = DateTime.Parse(xNode.Attributes.GetNamedItem("SubmitTime").Value);
                instruction.StartTime = DateTime.Parse(xNode.Attributes.GetNamedItem("StartTime").Value);

                instruction.DocumentTermListFilePath =
                    XmlDataUtil.GetAttributeValue(xNode, "DocumentTermListFilePath",
                                                  "");
                instruction.StartingClusterResultFilePath =
                    XmlDataUtil.GetAttributeValue(xNode,
                                                  "StartingClusterResultFilePath",
                                                  "");
                instruction.TermWeightFilePath = 
                    XmlDataUtil.GetAttributeValue(xNode, "TermWeightFilePath", "");
                instruction.IterationFilePath = 
                    XmlDataUtil.GetAttributeValue(xNode, "IterationFilePath", "");
                instruction.ClusterResultFileNamePattern =
                    XmlDataUtil.GetAttributeValue(xNode,
                                                  "ClusterResultFileNamePattern",
                                                  "");

                return instruction;
            }
            else
            {
                throw new Exception("Unable to instantiate instruction: invalid type specified in xml node");
            }
        }

        public override XmlNode Serialize(ref XmlDocument xDoc, ref XmlNode parentNode)
        {
            XmlNode xNode = XmlDataUtil.AddElement(ref xDoc, parentNode, "Instruction");
            XmlDataUtil.UpdateAttribute(ref xDoc, xNode, "Type", this.GetType().FullName);
            XmlDataUtil.UpdateAttribute(ref xDoc, xNode, "ComponentID", this.OwnerComponentID.ToString());
            XmlDataUtil.UpdateAttribute(ref xDoc, xNode, "WorkerID", this.OwnerWorkerInstanceID.ToString());
            XmlDataUtil.UpdateAttribute(ref xDoc, xNode, "SubmitTime", this.SubmitTime.ToString());
            XmlDataUtil.UpdateAttribute(ref xDoc, xNode, "StartTime", this.StartTime.ToString());

            XmlDataUtil.UpdateAttribute(ref xDoc,xNode,"DocumentTermListFilePath",this.DocumentTermListFilePath);
            XmlDataUtil.UpdateAttribute(ref xDoc, xNode, "StartingClusterResultFilePath",
                                        this.StartingClusterResultFilePath);
            XmlDataUtil.UpdateAttribute(ref xDoc, xNode,"TermWeightFilePath",this.TermWeightFilePath);
            XmlDataUtil.UpdateAttribute(ref xDoc, xNode, "IterationFilePath",this.IterationFilePath);
            XmlDataUtil.UpdateAttribute(ref xDoc, xNode, "ClusterResultFileNamePattern",
                                        this.ClusterResultFileNamePattern);

            return xNode;
        }
    }
}
